import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sainbainu/common/apis/common_api.dart';
import 'package:sainbainu/common/apis/user_api.dart';
import 'package:sainbainu/common/http/exception.dart';
import 'package:sainbainu/common/models/response/area_list_response.dart';
import 'package:sainbainu/common/models/response/upload_response.dart';
import 'package:sainbainu/common/models/response/user_info.dart';
import 'package:sainbainu/common/repositories/common_repository.dart';
import 'package:sainbainu/common/repositories/user_repository.dart';
import 'package:sainbainu/common/routes/routes.dart';
import 'package:sainbainu/common/services/ali_oss.dart';
import 'package:sainbainu/common/services/user.dart';
import 'package:sainbainu/common/utils/compress.dart';
import 'package:sainbainu/common/utils/custom_exception.dart';
import 'package:sainbainu/common/utils/image_cropper.dart';
import 'package:sainbainu/common/utils/loading.dart';
import 'package:sainbainu/common/utils/util.dart';
import 'package:sainbainu/common/values/assets_subtype_cn.dart';
import 'package:sainbainu/common/values/constant.dart';
import 'package:sainbainu/common/values/sizes.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

import 'index.dart';

/// 头像尺寸
const double kAvatarSize = 90;

class UserInfoController extends GetxController {
  UserInfoController();

  final state = UserInfoState();

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();

    /// 头部总高度
    state.headerExpandedHeight =
        kProfileCoverHeight + (kAvatarSize / 2) - kProfileTabbarHeight;
    state.scrollController = ScrollController();
    state.scrollController.addListener(() {
      calcTitleCollapsed();
    });
    state.userRepository = UserRepository(UserApi());
    state.commonRepository = CommonRepository(CommonApi());
    getUserProfile();
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
    state.scrollController.dispose();
    UserService.to.getAccountInfo();
  }

  /// 计算上滑头部完全折叠
  calcTitleCollapsed() {
    // android 端有精度问题 不ceil的话 offset没法一致
    bool isCollapsed = state.scrollController.offset.ceil() >=
        state.headerExpandedHeight - kToolbarHeight;
    if (state.isCollapsed.value != isCollapsed) {
      state.isCollapsed.value = isCollapsed;
    }
  }

  /// 获取用户资料
  Future<void> getUserProfile() async {
    var userProfile = await state.userRepository.userProfile();
    state.userProfileResponse = userProfile;
    update();
  }

  /// 修改封面
  void onEditCover() async {
    final AssetEntity? result = await handleChooseImage();
    if (result != null) {
      try {
        // AssetEntity 转 file 对象
        List<File> fileList = await Util.assetEntityToFiles([result]);
        // 压缩
        fileList = await CompressUtil().compressImages(
          CompressImagesOptions(fileList),
        );
        // 裁剪
        var file = await ImageCropperUtil.crop(
          fileList[0],
          compressQuality: 100,
          aspectRatio: ImageCropperRatio(
            ratioX: Get.width,
            ratioY: kProfileCoverHeight,
          ),
        );
        if (file == null) {
          return;
        }
        try {
          LoadingUtil.showLoading(text: '请稍后...');
          // 上传
          var url = await handleUpload(file);
          // 更新
          await state.userRepository.setCover(url);
          state.userProfileResponse.cover = url;
          update(['cover']);
          LoadingUtil.showSuccess('修改成功');
        } on CustomHttpException catch (e) {
          throw CustomException(e.message);
        } catch (e) {
          throw CustomException('出错了～');
        }
      } on CustomException catch (e) {
        LoadingUtil.showError(e.message);
      } catch (e) {
        LoadingUtil.showError(e.toString());
      }
    }
  }

  /// 修改头像
  void onEditAvatar() async {
    final AssetEntity? result = await handleChooseImage();
    if (result != null) {
      try {
        // AssetEntity 转 file 对象
        List<File> fileList = await Util.assetEntityToFiles([result]);
        if (fileList.isEmpty) {
          throw CustomException('图片解析失败，请稍后再试');
        }
        // 压缩
        fileList = await CompressUtil().compressImages(
          CompressImagesOptions(fileList),
        );
        // 裁剪
        var file = await ImageCropperUtil.crop(
          fileList[0],
          compressQuality: 90,
          aspectRatio: ImageCropperRatio(ratioX: 1, ratioY: 1),
        );
        if (file == null) {
          return;
        }
        try {
          LoadingUtil.showLoading(text: '请稍后...');
          // 上传
          var url = await handleUpload(file);
          // 更新
          await state.userRepository.setAvatar(url);
          state.userProfileResponse.avatar = url;
          update(['avatar']);
          LoadingUtil.showSuccess('修改成功');
        } on CustomHttpException catch (e) {
          throw CustomException(e.message);
        } catch (e) {
          throw CustomException('出错了～');
        }
      } on CustomException catch (e) {
        LoadingUtil.showError(e.message);
      } catch (e) {
        LoadingUtil.showError(e.toString());
      }
    }
  }

  /// 选择图片
  Future<AssetEntity?> handleChooseImage() async {
    final List<AssetEntity>? result = await AssetPicker.pickAssets(
      Get.context!,
      pickerConfig: AssetPickerConfig(
        maxAssets: 1,
        requestType: RequestType.image,
        previewThumbnailSize: const ThumbnailSize.square(200),
        pathNameBuilder: (path) {
          if (path.isAll) return '最近';
          return AssetsSubtypeCn.cnMap[path.name] ?? path.name;
        },
      ),
    );
    if (result != null) {
      // 过滤图片大小
      var newImages = await Util.filterAssetsEntiteis(result);
      if (newImages.isEmpty) {
        LoadingUtil.showError('请选择${AppConstant.imageMaxSize}MB以内的图');
      }
      return newImages[0];
    }
    return null;
  }

  /// 上传
  Future<String> handleUpload(File file) async {
    UploadResponse res = await AliOssService.to.upFile(
      file.path,
      mediaType: UploadMediaType.image,
    );
    return res.url;
  }

  /// 修改性别
  Future<void> handleUpdateGender(int gender) async {
    try {
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setGender(gender);
      state.userProfileResponse.gender = gender;
      update(['gender']);
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改昵称
  Future<void> onNickNameUpdate(String value) async {
    try {
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setNickname(value);
      state.userProfileResponse.nickName = value;
      update(['nickName']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改简介
  Future<void> onIntroUpdate(String value) async {
    try {
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setIntro(value);
      state.userProfileResponse.intro = value;
      update(['intro']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改唯一号
  Future<void> onUniqueNoUpdate(String value) async {
    try {
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setUniqueNo(value);
      state.userProfileResponse.uniqueNo = value;
      update(['uniqueNo']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改职位
  Future<void> onJobUpdate(String value) async {
    try {
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setJob(value);
      state.userProfileResponse.job = value;
      update(['job']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改地区
  Future<void> onAddressUpdate(
    AreaItemResponse province,
    AreaItemResponse? city,
    AreaItemResponse? county,
  ) async {
    try {
      String address = province.text;
      if (city != null) {
        address += ' ${city.text}';
      }
      if (county != null) {
        address += ' ${county.text}';
      }
      LoadingUtil.showLoading(text: '请稍后...');
      await state.userRepository.setAddress(address);
      state.userProfileResponse.seatAddress = address;
      update(['address']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 修改生日
  Future<void> onBirthPickerConfirm() async {
    if (state.birthTempDate == null) return;

    try {
      LoadingUtil.showLoading(text: '请稍后...');
      // 日期类转字符串yyyy-MM-dd
      String strYmd = state.birthTempDate!.toIso8601String().substring(0, 10);
      await state.userRepository.setBirthday(strYmd);
      state.userProfileResponse.birthday = strYmd;
      update(['birthday']);
      onBack();
      LoadingUtil.showSuccess('修改成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错了～');
    }
  }

  /// 滚动时存储生日日期
  void onBirthPickerChange(DateTime dateTime) {
    state.birthTempDate = dateTime;
  }

  /// 生日字符串转 DateTime
  DateTime? strBirthdayToDate(String? birthday) {
    if (birthday == null || birthday.isEmpty) return null;
    DateTime dateTime = DateTime.parse(birthday);
    return dateTime;
  }

  void onBack() {
    Get.back();
  }
}
